{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "Python快速体验："
      ],
      "metadata": {
        "id": "tOQLmJcyQgYw"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "JbRu2jvBP2sK"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "# 创建感知机(输入特征数为2)\n",
        "apple_detector = Perceptron(input_size=2)\n",
        "\n",
        "# 训练数据：颜色(1红/0绿), 形状(1圆/0非圆)\n",
        "X_train = np.array([[1,1], [1,0], [0,1], [0,0]])\n",
        "y_train = np.array([1, 0, 0, 0])  # 只有红+圆才是苹果\n",
        "\n",
        "# 训练100次\n",
        "apple_detector.train(X_train, y_train, epochs=100)\n",
        "\n",
        "# 预测新水果\n",
        "new_fruit = np.array([1,1])  # 红色且圆形\n",
        "print(f\"是苹果的概率：{apple_detector.predict(new_fruit)}\")  # 输出1"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "三、完整实现（带AND/OR测试）"
      ],
      "metadata": {
        "id": "FXsqk8EjQpb8"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "class Perceptron:\n",
        "  def __init__(self, input_size, lr=0.1):\n",
        "    \"\"\"\n",
        "    参数说明：\n",
        "    - input_size: 输入特征数量（如颜色+形状=2）\n",
        "    - lr: 学习率(建议0.01-0.1)\n",
        "    \"\"\"\n",
        "    self.weights = np.random.randn(input_size)*0.01  # 小随机初始化\n",
        "    self.bias = 0.0\n",
        "    self.lr = lr\n",
        "\n",
        "  def activate(self, z):\n",
        "    \"\"\"激活函数：简单开关\"\"\"\n",
        "    return 1 if z >= 0 else 0\n",
        "\n",
        "  def predict(self, x):\n",
        "    \"\"\"预测方法\"\"\"\n",
        "    return self.activate(np.dot(x, self.weights) + self.bias)\n",
        "\n",
        "  def train(self, X, y, epochs=100):\n",
        "    \"\"\"\n",
        "    训练过程：\n",
        "    - X: 训练数据矩阵\n",
        "    - y: 标签(0/1)\n",
        "    - epochs: 学习遍数\n",
        "    \"\"\"\n",
        "    for _ in range(epochs):\n",
        "        for xi, yi in zip(X, y):\n",
        "            # 转换为numpy数组以确保能进行向量运算\n",
        "            xi = np.array(xi)\n",
        "            # 计算预测值\n",
        "            y_pred = self.predict(xi)\n",
        "            # 计算误差\n",
        "            error = yi - y_pred\n",
        "            # 更新参数\n",
        "            self.weights += self.lr * error * xi\n",
        "            self.bias += self.lr * error\n",
        "\n",
        "# 测试不同逻辑\n",
        "def test_logic(name, X, y):\n",
        "  print(f\"\\n{name}逻辑测试：\")\n",
        "  p = Perceptron(input_size=2)\n",
        "  p.train(X, y)\n",
        "  for xi, yi in zip(X, y):\n",
        "    print(f\"输入{xi} → 预测{p.predict(xi)} (应得:{yi})\")\n",
        "\n",
        "# AND逻辑\n",
        "test_logic(\"AND\",\n",
        "        X=[[0,0],[0,1],[1,0],[1,1]],\n",
        "        y=[0,0,0,1])\n",
        "\n",
        "# OR逻辑\n",
        "test_logic(\"OR\",\n",
        "        X=[[0,0],[0,1],[1,0],[1,1]],\n",
        "        y=[0,1,1,1])\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "jZuwp-2CQtB8",
        "outputId": "a7297161-e3c6-4764-f2df-3448d2015747"
      },
      "execution_count": 15,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "AND逻辑测试：\n",
            "输入[0, 0] → 预测0 (应得:0)\n",
            "输入[0, 1] → 预测0 (应得:0)\n",
            "输入[1, 0] → 预测0 (应得:0)\n",
            "输入[1, 1] → 预测1 (应得:1)\n",
            "\n",
            "OR逻辑测试：\n",
            "输入[0, 0] → 预测0 (应得:0)\n",
            "输入[0, 1] → 预测1 (应得:1)\n",
            "输入[1, 0] → 预测1 (应得:1)\n",
            "输入[1, 1] → 预测1 (应得:1)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "突破单层感知机的局限：用多层感知机解决XOR问题"
      ],
      "metadata": {
        "id": "-us-GMR_TL1c"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import numpy as np\n",
        "\n",
        "class XOR_MLP:\n",
        "  def __init__(self):\n",
        "    \"\"\"修正后的双层感知机网络\"\"\"\n",
        "    # 重新调整的权重和偏置\n",
        "    self.hidden_weights = np.array([[20, 20],    # 第一个隐藏神经元权重\n",
        "                      [-20, -20]]) # 第二个隐藏神经元权重\n",
        "    self.hidden_bias = np.array([-10, 30])       # 隐藏层偏置\n",
        "\n",
        "    self.output_weights = np.array([20, 20])\n",
        "    self.output_bias = -30  # 输出层偏置\n",
        "\n",
        "  def sigmoid(self, x):\n",
        "    \"\"\"Sigmoid激活函数\"\"\"\n",
        "    return 1 / (1 + np.exp(-x))\n",
        "\n",
        "  def predict(self, x):\n",
        "    \"\"\"预测XOR结果\"\"\"\n",
        "    x = np.array(x)\n",
        "\n",
        "    # 隐藏层计算\n",
        "    hidden_z = np.dot(x, self.hidden_weights.T) + self.hidden_bias\n",
        "    hidden_output = self.sigmoid(hidden_z)\n",
        "\n",
        "    # 输出层计算\n",
        "    output_z = np.dot(hidden_output, self.output_weights) + self.output_bias\n",
        "    output = self.sigmoid(output_z)\n",
        "\n",
        "    # 四舍五入得到0或1\n",
        "    return int(round(output))\n",
        "\n",
        "# 创建并测试网络\n",
        "xor_mlp = XOR_MLP()\n",
        "print(\"XOR问题测试结果:\")\n",
        "for case, desc in [([0,0],\"0 XOR 0\"), ([0,1],\"0 XOR 1\"),\n",
        "  ([1,0],\"1 XOR 0\"), ([1,1],\"1 XOR 1\")]:\n",
        "  print(f\"{desc} -> {xor_mlp.predict(case)}\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "flOuxCDuTMVM",
        "outputId": "3dec414f-5674-46ae-d0ed-2c306600a5f4"
      },
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "XOR问题测试结果:\n",
            "0 XOR 0 -> 0\n",
            "0 XOR 1 -> 1\n",
            "1 XOR 0 -> 1\n",
            "1 XOR 1 -> 0\n"
          ]
        }
      ]
    }
  ]
}